const newId = (() => {
    let id = 0;
    return () => id++;
})();

function createClassStyle(sheet: CSSStyleSheet, prefix: string, template: TemplateStringsArray, args: any[]): string {
    const className = prefix + "-" + newId();
    const rule = `.${className} { ${String.raw(template, ...args)} }`;
    sheet.insertRule(rule);
    return className;
}

export class Styled {
    static new(): [Styled, (template: TemplateStringsArray, ...args: any[]) => void] {
        const styled = new Styled();
        function css(template: TemplateStringsArray, ...args: unknown[]) {
            styled.sheet.insertRule(String.raw(template, ...args));
        }
        return [styled, css];
    }

    readonly sheet: CSSStyleSheet;

    constructor() {
        this.sheet = new CSSStyleSheet();
    }

    class(prefix: string) {
        return (template: TemplateStringsArray, ...args: any[]) => {
            return createClassStyle(this.sheet, prefix, template, args);
        };
    }
}

export function css(template: TemplateStringsArray, ...args: unknown[]): CSSStyleSheet {
    const sheet = new CSSStyleSheet();
    const rule = String.raw(template, ...args);
    sheet.insertRule(rule);
    return sheet;
}
